from ctypes import cdll, c_float, c_uint, c_ulong, c_void_p, Structure, addressof, string_at, create_string_buffer, cast
import random

class LIBPERSEUS_HL(Structure) :
      _fields_ = [("Pcc", c_void_p),
                  ("NGen", c_void_p),
                  ("aKey", c_void_p),
                 ]

class Perseus :
   def __init__(self, path="../libperseus-1.0.3.so", aleas=[]) :
      self._p = cdll.LoadLibrary( path )
      self.lphl = LIBPERSEUS_HL()
      
      if aleas == [] :
         aleas = [ random.random() for i in range(0,4) ]

      ret = self._p.perseus_init( addressof( self.lphl ), c_float( aleas[0] ), c_float( aleas[1] ), c_float( aleas[2] ), c_float( aleas[3] ) )

      if ret == -1 :
         raise("ooo")

   def __del__(self) :
      self._p.perseus_destroy( addressof( self.lphl ) )

   def code(self, msg) :
      encoded_data_size = c_ulong()
      ret = self._p.perseus_code( addressof( self.lphl ), msg, len(msg), addressof( encoded_data_size ) )
      if ret == 0x0 :
         raise("ooo")

      s = string_at(ret, encoded_data_size.value)
      self._p.perseus_free( cast( ret, c_void_p ) )
      return s

   def decode(self, msg) :
      decoded_data_size = c_ulong()
      ret = self._p.perseus_decode( addressof( self.lphl ), msg, len(msg), addressof( decoded_data_size ) )
      if ret == 0x0 :
         raise("ooo")

      s = string_at(ret, decoded_data_size.value )
      self._p.perseus_free( cast( ret, c_void_p ) )
      return s
